package com.ry.novel.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ry.novel.enums.NovelConst;
import com.ry.novel.exception.BusinessException;
import com.ry.novel.mapper.BookIndexMapper;
import com.ry.novel.model.dto.BookIndexInfo;
import com.ry.novel.model.dto.BookInfo;
import com.ry.novel.model.entity.BookIndex;
import com.ry.novel.service.BookIndexService;
import com.ry.novel.service.BookService;
import com.ry.novel.utils.DateUtil;
import com.ry.novel.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional;
import sun.rmi.runtime.Log;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author ry
 * @since 2022-02-18 17:11
 **/
@Slf4j
@Service
public class BookIndexServiceImpl implements BookIndexService {
    @Autowired
    private BookIndexMapper bookIndexMapper;

    @Autowired
    private BookService bookService;

    private List<BookIndexInfo> queryIndexByBookId(Long bookId,Byte state){
        QueryWrapper<BookIndex> wrapper = new QueryWrapper<>();
        wrapper.eq("book_id",bookId);
        wrapper.eq("state",state);
        List<BookIndex> bookIndices = bookIndexMapper.selectList(wrapper);
        List<BookIndexInfo> infos = bookIndices.stream().map(entity -> {
            return getBookIndexInfo(entity);
        }).collect(Collectors.toList());

        return infos;
    }

    /**
     * 审核中的章节
     *
     * @param bookId
     * @return
     */
    @Override
    public List<BookIndexInfo> queryReviewIndexByBookId(Long bookId) {
        return queryIndexByBookId(bookId,NovelConst.BOOK_INDEX_REVIEW);
    }

    /**
     * 审核通过的章节
     *
     * @param bookId
     * @return
     */
    @Override
    public List<BookIndexInfo> queryPassedIndexByBookId(Long bookId) {
        return queryIndexByBookId(bookId,NovelConst.BOOK_INDEX_PASSED);
    }

    /**
     * 审核不通过的章节
     *
     * @param bookId
     * @return
     */
    @Override
    public List<BookIndexInfo> queryBiddenIndexByBookId(Long bookId) {
        return queryIndexByBookId(bookId,NovelConst.BOOK_INDEX_BIDDEN);
    }

    @Override
    public Map<String, List<BookIndexInfo>> bookIndexList(Long bookId) {
        Map<String,List<BookIndexInfo>> map = new HashMap<>();
        List<BookIndexInfo> reviewList = queryReviewIndexByBookId(bookId);
        List<BookIndexInfo> biddenList = queryBiddenIndexByBookId(bookId);
        List<BookIndexInfo> passedList = queryPassedIndexByBookId(bookId);

        map.put("reviewList",reviewList);
        map.put("biddenList",biddenList);
        map.put("passedList",passedList);

        return map;
    }

    /**
     * 根据bookId查询最新章节的num
     *
     * @param bookId
     * @return
     */
    @Override
    public Integer lastIndexNum(Long bookId) {
        QueryWrapper<BookIndex> wrapper = new QueryWrapper<>();
        //index_num最大的那一条记录
        wrapper.eq("book_id",bookId);
        wrapper.orderByDesc("index_num");
        wrapper.last("limit 1");


        BookIndex bookIndex = bookIndexMapper.selectOne(wrapper);


        return null == bookIndex ? 0 : bookIndex.getIndexNum();
    }

    /**
     * 作者发布章节
     *
     * @param bookIndexInfo
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void authorPublishBookIndex(BookIndexInfo bookIndexInfo) {
        BookIndex entity = new BookIndex();
        entity.setBookId(bookIndexInfo.getBookId());
        entity.setState(NovelConst.BOOK_INDEX_REVIEW);

        //先查出上一章节的num
        entity.setIndexNum(lastIndexNum(bookIndexInfo.getBookId()) + 1);
        entity.setIndexName(bookIndexInfo.getIndexName());
        entity.setCharge(NovelConst.BOOK_INDEX_IS_FREE);
        entity.setWordCount(StringUtil.getStrValidWordCount(bookIndexInfo.getContent()));
        entity.setCreateTime(LocalDateTime.now().toString());
        entity.setUpdateTime(LocalDateTime.now().toString());

        //将换行符和空白符转义
        String content = bookIndexInfo
                .getContent()
                .replaceAll("\\n","<br/>")
                .replace("<script>","")
                .replace("</script>","")
                .replaceAll("\\s","&nbsp;");
        entity.setContent(content);

        bookIndexMapper.insert(entity);

        BookInfo queryById = bookService.queryById(bookIndexInfo.getBookId());
        BookInfo bookInfo = new BookInfo();
        bookInfo.setId(queryById.getId());
        bookInfo.setLastIndexName(entity.getIndexName());
        bookInfo.setWordCount(queryById.getWordCount() + entity.getWordCount());
        bookInfo.setLastIndexId(entity.getId());
        bookInfo.setLastIndexUpdateTime(entity.getUpdateTime());
        bookService.updateBook(bookInfo);
    }

    /**
     * 作者修改章节
     *
     * @param info
     */
    @Override
    public void authorUpdateBookIndex(BookIndexInfo info) {
        BookIndex originIndex = bookIndexMapper.selectById(info.getId());
        //章节的原字数
        Integer originIndexWordCount = originIndex.getWordCount();

        BookInfo bookInfo = bookService.queryById(info.getBookId());
        //减去原章节的字数，加上新的章节字数
        bookInfo.setWordCount(bookInfo.getWordCount() - originIndexWordCount + StringUtil.getStrValidWordCount(info.getContent()));
        BookIndex bookIndex = new BookIndex();
        bookIndex.setId(info.getId());
        bookIndex.setBookId(info.getBookId());
        bookIndex.setIndexName(info.getIndexName());
        bookIndex.setWordCount(StringUtil.getStrValidWordCount(info.getContent()));
        bookIndex.setUpdateTime(LocalDateTime.now().toString());

        //将换行符和空白符转义
        String content = info
                .getContent()
                .replaceAll("\\n","<br/>")
                .replace("<script>","")
                .replace("</script>","")
                .replaceAll("\\s","&nbsp;");
        bookIndex.setContent(content);



        bookIndexMapper.updateById(bookIndex);

        //更新小说信息
        bookService.updateBook(bookInfo);
    }

    /**
     * 查询小说的第一章
     *
     * @param bookId
     */
    @Override
    public BookIndexInfo readFirstIndex(Long bookId) {
        QueryWrapper<BookIndex> wrapper = new QueryWrapper<>();
        wrapper.eq("book_id",bookId);
        wrapper.orderByAsc("index_num");
        wrapper.last("limit 1");
        wrapper.eq("state",NovelConst.BOOK_INDEX_PASSED);
        BookIndex bookIndex = bookIndexMapper.selectOne(wrapper);
        if (null == bookIndex){
            //还没有章节是通过审核的

            return null;
        }
        BookIndexInfo bookIndexInfo = getBookIndexInfo(bookIndex);
        bookIndexInfo.setBookName(bookService.queryById(bookIndex.getBookId()).getBookName());
        //根据bookId和indexNum查询上一章的id和下一章的id
        Integer indexNum = bookIndexInfo.getIndexNum();
        bookIndexInfo.setNextIndexId(getNextIndexId(bookId,indexNum));
        bookIndexInfo.setPreIndexId(getPreIndexId(bookId,indexNum));


        //增加浏览次数
        bookService.addBookVisitCount(bookId);
        return bookIndexInfo;
    }

    private Long getNextIndexId(Long bookId,Integer indexNum){
        QueryWrapper<BookIndex> wrapper = new QueryWrapper<>();
        wrapper.eq("book_id",bookId);
        //比当前indexNum大的第一条数据
        wrapper.gt("index_num",indexNum);
        wrapper.last("limit 1");
        BookIndex bookIndex = bookIndexMapper.selectOne(wrapper);
        if (bookIndex == null || !bookIndex.getState().equals(NovelConst.BOOK_INDEX_PASSED)){
            return Long.valueOf(-1);
        }

        return bookIndex.getId();
    }

    private Long getPreIndexId(Long bookId,Integer indexNum){
        QueryWrapper<BookIndex> wrapper = new QueryWrapper<>();
        wrapper.eq("book_id",bookId);
        //比当前indexNum小的第一条数据
        wrapper.lt("index_num",indexNum);
        wrapper.last("limit 1");
        BookIndex bookIndex = bookIndexMapper.selectOne(wrapper);

        if (bookIndex == null || !bookIndex.getState().equals(NovelConst.BOOK_INDEX_PASSED)){
            return Long.valueOf(-1);
        }

        return bookIndex.getId();
    }

    /**
     * 根据章节id查询
     *
     * @param indexId
     */
    @Override
    public BookIndexInfo queryById(Long indexId) {
        BookIndex entity = bookIndexMapper.selectById(indexId);
        BookIndexInfo bookIndexInfo = getBookIndexInfo(entity);

        String content = bookIndexInfo
                .getContent()
                .replaceAll("&nbsp;"," ")
                .replaceAll("<br/>","\n")
                .replaceAll("<br />","\n");
        bookIndexInfo.setContent(content);
        bookIndexInfo.setBookName(bookService.queryById(entity.getBookId()).getBookName());

        return bookIndexInfo;
    }

    @Override
    public List<BookIndexInfo> queryLastIndices(Long id) {
        QueryWrapper<BookIndex> wrapper = new QueryWrapper<>();
        //选取通过审核的章节号最新的前5条
        wrapper.eq("state",NovelConst.BOOK_INDEX_PASSED);
        wrapper.eq("book_id",id);
        wrapper.orderByDesc("index_num");
        wrapper.last("limit 0,5");

        List<BookIndex> bookIndices = bookIndexMapper.selectList(wrapper);
        List<BookIndexInfo> infos = bookIndices.stream().map(entity -> {
            BookIndexInfo info = getBookIndexInfo(entity);
            return info;
        }).collect(Collectors.toList());

        return infos;
    }

    @Override
    public BookIndexInfo readerQueryIndexById(Long indexId) {
        QueryWrapper<BookIndex> wrapper = new QueryWrapper<>();
        wrapper.eq("id",indexId);
        wrapper.eq("state",NovelConst.BOOK_INDEX_PASSED);
        BookIndex bookIndex = bookIndexMapper.selectOne(wrapper);
        BookIndexInfo bookIndexInfo = getBookIndexInfo(bookIndex);
        //根据bookId和indexNum查询上一章的id和下一章的id
        Integer indexNum = bookIndex.getIndexNum();
        bookIndexInfo.setBookName(bookService.queryById(bookIndex.getBookId()).getBookName());
        bookIndexInfo.setNextIndexId(getNextIndexId(bookIndex.getBookId(),indexNum));
        bookIndexInfo.setPreIndexId(getPreIndexId(bookIndex.getBookId(),indexNum));

        bookService.addBookVisitCount(bookIndex.getBookId());

        return bookIndexInfo;
    }

    @Override
    public List<BookIndexInfo> queryIndicesByBookId(Long bookId) {
        QueryWrapper<BookIndex> wrapper = new QueryWrapper<>();
        wrapper.select("id","index_name");
        wrapper.eq("state",NovelConst.BOOK_INDEX_PASSED);
        wrapper.eq("book_id",bookId);
        wrapper.orderByAsc("index_num");
        List<BookIndex> bookIndices = bookIndexMapper.selectList(wrapper);

        List<BookIndexInfo> infoList = bookIndices.stream().map(entity -> {
            BookIndexInfo bookIndexInfo = new BookIndexInfo();
            bookIndexInfo.setId(entity.getId());
            bookIndexInfo.setIndexName(entity.getIndexName());

            return bookIndexInfo;
        }).collect(Collectors.toList());

        return infoList;
    }

    @Override
    public void deleteById(Long id) {
        bookIndexMapper.deleteById(id);
    }


    private BookIndexInfo getBookIndexInfo(BookIndex entity) {
        BookIndexInfo bookIndexInfo = new BookIndexInfo();
        bookIndexInfo.setId(entity.getId());
        bookIndexInfo.setBookId(entity.getBookId());
        bookIndexInfo.setContent(entity.getContent().replaceAll("<br&nbsp;/>","<br />"));
        bookIndexInfo.setState(entity.getState());
        bookIndexInfo.setIndexNum(entity.getIndexNum());
        bookIndexInfo.setIndexName(entity.getIndexName());
        bookIndexInfo.setCharge(entity.getCharge());
        bookIndexInfo.setWordCount(entity.getWordCount());
        bookIndexInfo.setCreateTime(DateUtil.format(entity.getCreateTime()));
        bookIndexInfo.setReason(entity.getReason());
        bookIndexInfo.setUpdateTime(DateUtil.format(entity.getUpdateTime()));

        return bookIndexInfo;
    }
}
